package com.example.base.websocket;

import com.alibaba.fastjson.JSONObject;
import com.example.base.security.SysUserType;
import com.example.base.security.jwt.JWTTokenUtil;
import com.example.base.security.service.SysUserService;
import com.example.base.system.domain.OpenUserToken;
import com.example.base.system.service.OpenUserTokenService;
import com.example.base.utils.Result;
import com.example.base.utils.SpringContextUtils;
import com.example.base.websocket.plugin.AppWebSocketMap;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Component
public class AppWebSocketHandler extends TextWebSocketHandler {


    @Autowired
    AppWebSocketMap appWebSocketMap;


    /**
     * socket 建立成功事件
     *
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        HttpHeaders httpHeaders=session.getHandshakeHeaders();
        List<String> openTokenList=httpHeaders.get("openToken");
        String openToken=null;
        if(openTokenList!=null && openTokenList.size()>0){
            openToken=openTokenList.get(0);
        }
        String token=null;
        List<String> stringList=httpHeaders.get("token");
        if(stringList!= null && stringList.size() >0){
            token=stringList.get(0);
        }
        String appName=WsAppSessionManager.getAppName(session.getUri().getPath());
        if(StringUtils.isNotBlank(openToken)) {
            OpenUserTokenService tokenService=SpringContextUtils.getBean(OpenUserTokenService.class);
            OpenUserToken userToken=tokenService.valited(openToken);
            if(userToken!=null){
                SocketModel socketModel=new SocketModel();
                socketModel.setUserId(userToken.getUserid());
                socketModel.setUserName(userToken.getUsername());
                socketModel.setUserType(SysUserType.SYSTEM.getUserType());
                socketModel.setWebSocketSession(session);
                WsAppSessionManager.addAppSocketModel(appName,userToken.getUserid(),socketModel);
                JSONObject jsonObject=Result.successInfo("连接成功");
                session.sendMessage(new TextMessage(jsonObject.toJSONString()));
            }
        }else if(StringUtils.isNotBlank(token)) {
            Claims claims=JWTTokenUtil.getClaimsByToken(token);
            if(claims==null){
                JSONObject jsonObject= Result.errorInfo("当前用户未登录");
                session.sendMessage(new TextMessage(jsonObject.toJSONString()));
                session.close();
            }
            String userId=claims.getId();
            String username = claims.getSubject();
//            SysUserService service=SpringContextUtils.getBean(SysUserService.class);
//            service.selectUserByName(username);
            SocketModel socketModel=new SocketModel();
            socketModel.setUserId(userId);
            socketModel.setUserName(username);
            socketModel.setUserType(SysUserType.SYSTEM.getUserType());
            socketModel.setWebSocketSession(session);
            WsAppSessionManager.addAppSocketModel(appName,userId,socketModel);
            JSONObject jsonObject=Result.successInfo("连接成功");
            session.sendMessage(new TextMessage(jsonObject.toJSONString()));
        }else {
            JSONObject jsonObject= Result.errorInfo("当前用户未登录");
            session.sendMessage(new TextMessage(jsonObject.toJSONString()));
            session.close();
        }
    }


    /**
     * 接收消息事件
     *
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String appName=WsAppSessionManager.getAppName(session.getUri().getPath());
        String payload = message.getPayload();
        log.info("收到消息:{}",message.getPayload());

        // 获得客户端传来的消息
        log.info("sessionId: {}",session.getId());
        SocketModel socketModel= WsAppSessionManager.getUserIdBySessionId(appName,session.getId());
        if(socketModel==null){
            JSONObject result=Result.errorInfo("用户登录已过期");
            session.sendMessage(new TextMessage(result.toJSONString()));
            session.close();
        }else {
            session.sendMessage(new TextMessage("appName: "+appName+" server 接收到消息 " + payload + " " + LocalDateTime.now().toString()));
            session.sendMessage(new TextMessage("username: "+socketModel.getUserName()));
            List<AppWebSocket> list= appWebSocketMap.getAppWebSocketList();
            if(list!=null){
                list.forEach((e)->{
                    e.handlerTextMessage(session,message);
                });
            }
        }
    }

    /**
     * socket 断开连接时
     *
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String appName=WsAppSessionManager.getAppName(session.getUri().getPath());
        WsAppSessionManager.remove(appName,session.getId());
    }
}
